package com.tanhua.server.service;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.templates.AipFaceTemplate;
import com.tanhua.commons.templates.HuanXinTemplate;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.commons.templates.SmsTemplate;
import com.tanhua.domain.db.User;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.RecommendUser;
import com.tanhua.domain.vo.ErrorResult;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.UserInfoVo;
import com.tanhua.domain.vo.UserLikeListVo;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.FriendApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.JwtUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.sound.sampled.Line;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;

/**
 * service：
 *   1、业务逻辑封装
 *      查询之后，数据存入缓存，操作之后，发送短信
 *   2、数据封装
 */
@Service
public class UserSerivce {

    @Reference
    private UserApi userApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private SmsTemplate smsTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Autowired
    private OssTemplate ossTemplate; //文件上传

    @Autowired
    private AipFaceTemplate aipFaceTemplate; //人脸识别

    private String redisKey = "CHECK_CODE_";

    @Value("${tanhua.secret}")
    private String secret;

    //发送短信验证码
    public ResponseEntity sendMsg(String mobile) {
        //1、生成6为随机验证码   100000 - 999999
        //int mun = (int) (Math.random() * 9 + 1) * 100000 ;
        //String code = mun + "";
        String code = "111111";
        //2、调用SmsTemplate发送短信
        //smsTemplate.sendSms(mobile, code);
        //3、将验证码存入redis
        redisTemplate.opsForValue().set(redisKey+mobile, code, Duration.ofMinutes(5));
        //4、返回
        return ResponseEntity.ok(null);
    }

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * 验证码校验登录
     */
    public ResponseEntity login(String mobile, String code) {
        //1、获取redis中存入的验证码
        String value = redisTemplate.opsForValue().get(redisKey+mobile);
        //2、判断redis中的验证码是否存在并比较验证码是否一致
        if(value == null || !value.equals(code)) {
            //2.1 如果验证码错误，构造错误信息
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }
        redisTemplate.delete(redisKey+mobile) ;// 清楚redis中的验证码数据
        //3、根据手机号码查询用户
        User user = userApi.findByMobile(mobile);
        //3、1 如果用户不存在，创建用户对象存入数据库
        boolean isNew = false;

        String type = "0101" ;//默认登录
        if(user == null) {
            user = new User();
            user.setMobile(mobile);
            user.setPassword(DigestUtils.md5Hex("123456"));
            Long userId = userApi.save(user);
            user.setId(userId);
            isNew = true;
            //将新用户信息，注册到环信
            huanXinTemplate.register(user.getId());
            type="0102";//注册
        }

        try {
            Map<String,String> message = new HashMap<>();
            message.put("userId",user.getId().toString());
            message.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
            message.put("type", type);
            rocketMQTemplate.convertAndSend("tanhua-log",JSON.toJSONString(message));
        }catch (Exception e) {}


        String token = JwtUtils.createToken(mobile,user.getId(),secret);
        //4、将用户数据存入redis中
        //用户对象转化为json
        String jsonString = JSON.toJSONString(user);//将对象转化为json字符串
        //JSON.parseObject() //将json字符串，转化为指定的java对象
        //存入redis，设置失效时间
        redisTemplate.opsForValue().set("TOKEN_"+token,jsonString,Duration.ofHours(1));
        //5、构造返回值
        Map map = new HashMap();
        map.put("token", token);
        map.put("isNew",isNew);
        return ResponseEntity.ok(map);
    }

    //根据登录token，获取用户对象
    public User findUserByToken(String token) {
        String userStr = redisTemplate.opsForValue().get("TOKEN_"+token);
        if(userStr == null) {
            return null;
        }
        redisTemplate.opsForValue().set("TOKEN_" + token,userStr,Duration.ofHours(1));//续期
        return JSON.parseObject(userStr,User.class);
    }

    //保存用户信息
    public ResponseEntity saveUserInfo(UserInfo userInfo, String token) {
        //1通过token获取用户对象
        User user = findUserByToken(token);
        //2、设置用户id
        userInfo.setId(user.getId());
        //3、调用api完成保存
        userInfoApi.save(userInfo);
        //4、响应数据
        return ResponseEntity.ok(null);
    }

    //更新用户的头像图片
    public ResponseEntity updateUserHead(MultipartFile headPhoto, String token) throws IOException {
        //1、根据token获取用户
        User user = findUserByToken(token);
        //2、判断图片是否包含人脸
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        if(!detect) {
            return ResponseEntity.status(500).body(ErrorResult.faceError());
        }
        //3、将图片上传到阿里OSS，获取访问路径
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());//图片名，文件输入流
        //4、构造更新的用户信息对象
        UserInfo info = new UserInfo();
        info.setId(user.getId());
        info.setAvatar(url);
        //5、调用API更新用户信息
        userInfoApi.update(info);
        //6、构造返回值
        return ResponseEntity.ok(null);
    }

    //根据用户id，查询用户信息
    public ResponseEntity findUserInfoById(Long id) {
        //1、调用api，根据id查询用户
        UserInfo userInfo = userInfoApi.findById(id);
        //2、数据转化
        UserInfoVo vo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo, vo); //将第一个对象的同名同类型copy到第二个对象中
        if(userInfo.getAge() != null) {
            vo.setAge(userInfo.getAge().toString());
        }
        //3、构造返回值
        return ResponseEntity.ok(vo);
    }

    //更新用户信息
    public ResponseEntity updateUserInfo(UserInfo info, String token) {
        //1、通过token获取当前操作的用户对象
        User user = findUserByToken(token);
        //2、想userinfo中设置用户id
        info.setId(user.getId());
        //3、调用userinfoApi更新数据库
        userInfoApi.update(info);
        //4、构造返回值
        return ResponseEntity.ok(null);
    }

    /**
     * 修改手机号码，验证码校验
     *  verification
     */
    public ResponseEntity checkVerificationCode(String code) {
        //1、获取当前用户手机号
        String mobile = UserHolder.getUser().getMobile();
        //2、从redis中查询验证码
        String value = redisTemplate.opsForValue().get(redisKey+mobile);
        //3、判断验证码是否正确
        boolean verification = true;
        if(value == null || !value.equals(code)) {
            //3.1 验证码错误
            verification = false;
        }else {
            //3.2 验证码正确
            redisTemplate.delete(redisKey+mobile);
        }
        Map map = new HashMap();
        map.put("verification",verification);
        return ResponseEntity.ok(map);
    }

    //

    /**
     * 更新用户的手机号码
     *  mobile : 新手机号码
     */
    public ResponseEntity updateUserMobile(String mobile) {
        //1、根据手机号码查询用户是否存在
        User newUser = userApi.findByMobile(mobile);
        //2、如果已经存在返回手机号码已注册
        if(newUser != null) {
            return ResponseEntity.status(500).body(ErrorResult.mobileError());
        }
        //3、不存在，向用户对象设置最新的手机号码
        User user = UserHolder.getUser();
        user.setMobile(mobile);
        //4、调用API，更新用户
        userApi.update(user);
        //5、构造返回值
        return ResponseEntity.ok(null);
    }

    @Reference
    private UserLikeApi userLikeApi;

    @Reference
    private FriendApi friendApi;

    @Autowired
    private HuanXinTemplate template;

    //统计好友数，喜欢数，粉丝数
    public ResponseEntity queryCounts() {
        //1、获取用户id
        Long userId = UserHolder.getUserId();
        //2、根据用户id，查询此用户的好友数量
        Long eachCount = userLikeApi.queryEachLikeCount(userId);
        //3、根据用户id，查询此用户喜欢的用户数量
        Long likeCount = userLikeApi.queryLikeCount(userId);
        //4、根据用户id，查询此用户被喜欢的数量
        Long fanCount = userLikeApi.queryFanCount(userId);
        //5、构造返回
        Map map = new HashMap();
        map.put("eachLoveCount", eachCount);
        map.put("loveCount", likeCount);
        map.put("fanCount", fanCount);
        return ResponseEntity.ok(map);
    }

    /**
     * 互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表
     * type:
     *   1 互相关注    Friend
     *   2 我关注      UserLike
     *   3 粉丝        UserLike
     *   4 谁看过我     Vistors
     */
    public ResponseEntity queryUserLikeList(Integer page, Integer pagesize, Integer type) {
        //1、获取当前用户的用户id
        Long userId = UserHolder.getUserId();
        //2、根据查询类型，调用不同的API方法，查询数据 （统一成RecommonUser）
        PageResult result = new PageResult(page,pagesize,0,new ArrayList<>());
        switch (type) {
            case 1: {  //相互关注：好友
                result = userLikeApi.queryEachLikeList(page,pagesize,UserHolder.getUserId());
                break;
            }
            case 2: { //我喜欢的用户列表
                result = userLikeApi.queryLikeList(page,pagesize,UserHolder.getUserId());
                break;
            }
            case 3: { //查询喜欢我的
                result = userLikeApi.queryFanList(page,pagesize,UserHolder.getUserId());
                break;
            }
            case 4: { //查询访问记录
                result = userLikeApi.queryVisitorList(page,pagesize,UserHolder.getUserId());
                break;
            }
        }
        //3、获取查询数据列表
        List<RecommendUser> items = (List<RecommendUser>) result.getItems();
        //4、循环数据列表，一个对象构造一个vo
        List<UserLikeListVo> list = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo info = userInfoApi.findById(item.getUserId());
            UserLikeListVo vo = new UserLikeListVo();
            BeanUtils.copyProperties(info,vo);
            vo.setMatchRate(item.getScore().intValue());
            list.add(vo);
        }
        //5、构造返回值
        result.setItems(list);
        return ResponseEntity.ok(result);
    }

    /**
     * 对关注我的粉丝，进行喜欢操作
     *  likeUserId ： 粉丝的用户id
     */
    public ResponseEntity fansLike(Long likeUserId) {
        //1、删除粉丝的关注数据
        userLikeApi.delete(likeUserId,UserHolder.getUserId());
        //2、记录双向的好友关系
        friendApi.save(UserHolder.getUserId(),likeUserId);
        //3、注册好友关系到环信
        template.contactUsers(UserHolder.getUserId(),likeUserId);
        return ResponseEntity.ok(null);
    }
}
